{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第二章 快速入门"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "本章节将为读者提供一个快速入门PyTorch的指南，其中2.1节将介绍如何安装配置PyTorch，以及如何配置相应的学习环境；在2.2节中笔者将带领读者快速浏览PyTorch中的主要内容，以便于读者建立一个关于PyTorch的大致印象。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.1 安装与配置\n",
    "\n",
    "PyTorch是一款使用Python语言主导开发的轻量级深度学习框架。在使用PyTorch之前，读者需要安装Python环境以及pip包管理工具，这里笔者推荐使用Anaconda配置相关虚拟环境。本书中所有代码均使用PyTorch 1.6版本，并全部在Python3环境中运行得到最终结果。本书默认使用Linux作为开发环境。\n",
    "\n",
    "为了方便用户安装使用，PyTorch官方提供了多种安装方法。本节将介绍几种常用的安装方式，读者可以根据自己的需求进行选择。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.1.1 Linux系统下安装PyTorch"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 使用pip安装\n",
    "\n",
    "目前，使用pip安装PyTorch二进制包是最简单、最不容易出错，同时也是最适合新手的安装方式。读者可以从PyTorch官网上选择操作系统、包管理器pip、编程语言及CUDA版本，从而得到对应的安装命令，如图2-1所示。\n",
    "![图2-1  使用pip安装PyTorch(Linux)](imgs/使用pip安装PyTorch.png)\n",
    "\n",
    "以Linux平台、pip安装、PyTorch 1.6及CUDA 10.1为例，安装命令如下：\n",
    "```\n",
    "pip install torch==1.6.0+cu101 torchvision==0.7.0+cu101 -f https://download.pytorch.org/whl/torch_stable.html\n",
    "```\n",
    "待全部安装完成后，打开Python，运行如下命令\n",
    "```\n",
    "import torch as t\n",
    "```\n",
    "若没有报错则表示PyTorch安装成功。在安装PyTorch时需要注意以下两点：\n",
    "1. PyTorch对应的Python包名为torch而非pytorch；\n",
    "2. 若需使用GPU版本的PyTorch，读者需要先配置英伟达显卡驱动，再安装PyTorch。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 使用conda安装\n",
    "conda是Anaconda自带的包管理器，如果读者使用Anaconda作为Python环境，则除了使用pip安装PyTorch之外，还可以使用conda进行安装。同样，读者可以从PyTorch官网上选择操作系统、包管理器conda、编程语言及CUDA版本，从而得到对应的安装命令，如图2-2所示。\n",
    "![图2-2  使用conda安装PyTorch(Linux)](imgs/使用conda安装PyTorch.png)\n",
    "以Linux平台、conda安装、PyTorch 1.6及CUDA 10.1为例，安装命令如下：\n",
    "```\n",
    "conda install pytorch==1.6.0 torchvision==0.7.0 cudatoolkit=10.1 -c pytorch\n",
    "```\n",
    "其中，`-c pytorch`表示从官网下载安装，速度可能较慢，因此对于国内用户，尤其是教育网用户将conda源其更换为清华镜像源，参考命令如下：\n",
    "```\n",
    "conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/\n",
    "conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/\n",
    "conda config --set show_channel_urls yes\n",
    "```\n",
    "在配置完清华镜像源后读者便可使用官网中去掉`-c pytorch`的命令较快地通过conda完成PyTorch的安装了。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.1.2 Windows系统下安装PyTorch\n",
    "\n",
    "#### 使用pip安装\n",
    "\n",
    "对于PyTorch 1.6，官网提供了基于pip的包管理器的安装方法，同样选择操作系统、包管理器pip，编程语言以及CUDA版本，如图2-3所示：\n",
    "![图2-3  使用pip安装PyTorch(Windows)](imgs/使用pip安装PyTorch(Windows).png)\n",
    "\n",
    "为了加快速度，我们还可以将其中的源更改为清华源后运行（以CUDA 10.1为例）：\n",
    "```\n",
    "pip install torch==1.6.0+cu101 torchvision==0.7.0+cu101 -i https://pypi.tuna.tsinghua.edu.cn/simple\n",
    "```\n",
    "\n",
    "#### 使用conda安装\n",
    "\n",
    "与Linux系统下的安装类似，进行相应选择后官网提供的命令界面如图2-4所示：\n",
    "![图2-4  使用conda安装PyTorch(Windows)](imgs/使用conda安装PyTorch(Windows).png)\n",
    "\n",
    "为了加快安装的速度，我们同样可以配置清华镜像源，其命令与Linux系统下清华镜像源的配置命令一致。然而在Windows系统下配置镜像地址可能出现错误，一种可能的解决方案便是更改设备的网络以及Internet选项，具体来说，读者可以在链接选项卡中选择局域网设置，而后配置成为自动检测设置即可，如图2-5所示：\n",
    "![图2-5  更改Windows设置以更换镜像源](imgs/更改Windows设置以更换镜像源.png)\n",
    "\n",
    "在配置完清华镜像源后读者便可使用官网中去掉`-c pytorch`的命令较快地通过conda完成PyTorch的安装了。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.1.3 学习工具介绍\n",
    "\n",
    "工欲善其事，必先利其器。在从事科学计算相关工作时，IPython和Jupyter是两个必不可少的工具，这里笔者推荐使用IPython和Jupyter Notebook来学习本书的示例代码。同时，类似的开发工具还有PyCharm以及Visual Studio Code(VS Code)。笔者认为，Jupyter Notebook中聚合了网页与可视化，十分便捷易用；PyCharm则较为冗余，更适合一些复杂项目的开发，同时较多功能需要使用付费的专业版；至于VS Code，其生态环境已经十分成熟，且提供了许多易用的插件。因此，本节将向读者介绍VS Code、IPython以及Jupyter Notebook的安装与使用"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Visual Studio Code\n",
    "\n",
    "VS Code是一款由微软开发，并支持各种语言的编辑器。VS Code十分适合用户进行远程开发，其支持SSH传输协议，可用于连接远程服务器。同时，VS Code提供了十分丰富的插件以便于用户的使用，如Python（用于代码调试、变量检测等）、Remote-SSH(用于连接远程服务器)以及Jupyter（用于加载Jupyter Notebook）等。\n",
    "\n",
    "VS Code可在其官网上直接下载，目前支持Windows、Linux以及macOS系统。在成功安装VS Code后，读者可以通过左侧菜单栏下载相关插件，如图2-6所示。\n",
    "![图2-6 VSCode插件](imgs/VSCode插件.png)\n",
    "\n",
    "在安装Python插件及Jupyter插件后，读者便可直接使用VS Code打开.py以及.ipynb文件。VS Code提供了自动补全、悬停提示等十分贴心的功能，因此它十分适合Python的入门者进行后续进一步的学习。\n",
    "\n",
    "![图2-7 VSCode中使用Jupyter Notebook](imgs/VSCode中使用JupyterNotebook.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### IPython\n",
    "\n",
    "IPython是一个交互式计算系统，可认为是增强版的Python Shell，提供强大的REPL(交互式解析器)功能。对于从事科学计算的用户来说，它提供方便的可交互式学习及调试功能。\n",
    "\n",
    "安装IPython十分简单，读者可以通过以下命令安装IPython：\n",
    "```\n",
    "pip install ipython\n",
    "```\n",
    "安装完成后，在命令行输入`ipython`即可启动IPython，启动界面如下：\n",
    "```\n",
    "Python 3.6.13 | packaged by conda-forge | (default, Feb 19 2021, 05:36:01) \n",
    "Type 'copyright', 'credits' or 'license' for more information\n",
    "IPython 7.16.1 -- An enhanced Interactive Python. Type '?' for help.\n",
    "\n",
    "In [1]: import torch as t\n",
    "```\n",
    "\n",
    "输入`exit`命令或者按下`Ctrl+D`快捷键即可退出IPython。IPython具有许多强大的功能，其中最常用的功能如下。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**自动补全**    IPython最方便的功能之一是自动补全，当输入一个函数或者变量的前几个字母，按下`Tab`键，就能实现自动补全，如图2-8所示。\n",
    "\n",
    "![图2-8 IPython自动补全](imgs/IPython自动补全.png)\n",
    "\n",
    "**内省**    所谓内省，主要是指在Runtime时获得一个对象的全部类型信息，这对实际的学习有很大帮助。输入某一个函数，或者模块之后，接着输入`?`可看到它对应的帮助文档，有些帮助文档比较长，可能跨页，这时可输入空格键翻页，输入`q`退出。例如：\n",
    "```\n",
    "In [1]: import torch as t\n",
    "\n",
    "In [2]: t.abs? #查看abs函数的文档\n",
    "Docstring:\n",
    "abs(input, out=None) -> Tensor\n",
    "\n",
    "Computes the element-wise absolute value of the given :attr:`input` tensor.\n",
    "\n",
    ".. math::\n",
    "    \\text{out}_{i} = |\\text{input}_{i}|\n",
    "\n",
    "Args:\n",
    "    input (Tensor): the input tensor.\n",
    "    out (Tensor, optional): the output tensor.\n",
    "\n",
    "Example::\n",
    "\n",
    "    >>> torch.abs(torch.tensor([-1, -2, 3]))\n",
    "    tensor([ 1,  2,  3])\n",
    "Type:      builtin_function_or_method\n",
    "```\n",
    "在函数或模块名之后输入两个问号，例如`t.FloatTensor??`即可查看这个对象的源码（仅能查看对应Python的源码，无法查看C/C++的源码）。\n",
    "\n",
    "**快捷键**    IPython提供了很多快捷键，例如，按上箭头，可以重新输入上一条代码；一直按上箭头，可以追溯到之前输入的代码。按\"Ctrl+C\"快捷键可以清空当前输入或停止运行的程序。常用的快捷键如表2-1所示。\n",
    "        \n",
    "\n",
    "  <p align=\"center\"> 表2-1 IPython常用快捷键 </p>\n",
    "\n",
    "|     快捷键     |                      功能                      |\n",
    "| :------------: | :--------------------------------------------: |\n",
    "| Ctrl+P或上箭头 | 搜索之**前**命令历史中以当前输入文本开头的命令 |\n",
    "| Ctrl+N或下箭头 | 搜索之**后**命令历史中以当前输入文本开头的命令 |\n",
    "|  Ctrl+Shift+V  |                粘贴代码或代码块                |\n",
    "|     Ctrl+A     |                   跳转到行头                   |\n",
    "|     Ctrl+E     |                   跳转到行尾                   |\n",
    "\n",
    "**魔术方法**    IPython中还提供了一些特殊的命令，这些命令以`%`开头，称为魔术命令，例如可通过`%hist`查看在当前IPython下的输入历史等，示例如下。\n",
    "\n",
    "```python\n",
    "In [1]: import torch as t\n",
    "\n",
    "In [2]: a=t.Tensor(3,4)\n",
    "\n",
    "In [3]: %timeit a.sum() #检测某条语句的执行时间\n",
    "1000000 loops, best of 3: 359 ns per loop\n",
    "```\n",
    "\n",
    "```python\n",
    "In [4]: %hist # 查看输入历史\n",
    "import torch as t\n",
    "a=t.Tensor(3,4)\n",
    "%timeit a.sum()\n",
    "%hist\n",
    "\n",
    "In [5]: %paste #执行粘贴板中的代码，如果只粘贴不执行使用Ctrl+Shift+V\n",
    "def add(x,y,z):\n",
    "     return x+y+z\n",
    "## -- End pasted text --\n",
    "\n",
    "In [6]: %cat a.py # 查看某一个文件的内容，这个文件只有两行代码\n",
    "b = a + 1\n",
    "print(b.size())\n",
    "\n",
    "In [7]: %run -i a.py # 执行文件,-i选项代表在当前命名空间中执行\n",
    "                     # 此时会使用当前命名空间中的变量，结果也会返回至当前命名空间\n",
    "(3L,)\n",
    "\n",
    "In [8]: b \n",
    "Out[8]: \n",
    "\n",
    "-4.5902e-22\n",
    " 4.5577e-41\n",
    " 1.1404e-11\n",
    "[torch.FloatTensor of size 3]\n",
    "```\n",
    "\n",
    "和普通Python对象一样，魔术方法也支持自省，因此也可在命令后面加\"?\"或\"??\"来查看对应的帮助文档或源代码，例如通过`%run?`可查看它的使用说明。其它常用魔术命令如表2-2所示。\n",
    "\n",
    "表2-2: IPython常用魔术命令\n",
    "\n",
    "|   命令    |                 说明                  |\n",
    "| :-------: | :-----------------------------------: |\n",
    "| %quickref |             显示快速参考              |\n",
    "| %who/%who |       显示当前命名空间中的变量        |\n",
    "|  %debug   |         进入调试模式(按q退出)         |\n",
    "|  %magic   |           查看所有魔术命令            |\n",
    "|   %env    |           查看系统环境变量            |\n",
    "|   %xdel   | 删除变量并删除其在IPython上的一切引用 |\n",
    "\n",
    "`％xdel`与`del`的不同在于前者会删除其在IPython上的一切引用，具体例子如下。\n",
    "\n",
    "```python\n",
    "In [1]: import torch as t                                                  \n",
    "                                            \n",
    "In [2]: a=t.Tensor(5,5)\n",
    "                                          \n",
    "                                            \n",
    "Out[3]: \n",
    "\n",
    "1.00000e-16 *\n",
    "  8.4887  0.0000  8.4887  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "[torch.FloatTensor of size 5x5]\n",
    "\n",
    "In [4]: del a #并未彻底释放空间，因为这块空间还被Out[3]所引用\n",
    "\n",
    "In [5]: c=t.Tensor(1000,1000)\n",
    "\n",
    "In [6]: c\n",
    "Out[6]: \n",
    "\n",
    "    0     0     0  ...      0     0     0\n",
    "    0     0     0  ...      0     0     0\n",
    "    0     0     0  ...      0     0     0\n",
    "       ...          ⋱          ...       \n",
    "    0     0     0  ...      0     0     0\n",
    "    0     0     0  ...      0     0     0\n",
    "    0     0     0  ...      0     0     0\n",
    "[torch.FloatTensor of size 1000x1000]\n",
    "\n",
    "In [7]: %xdel c\n",
    "\n",
    "In [8]: Out [3]\n",
    "Out[8]: \n",
    "\n",
    "1.00000e-16 *\n",
    "  8.4887  0.0000  8.4887  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "[torch.FloatTensor of size 5x5]\n",
    "\n",
    "In [9]: Out[6]\n",
    "---------------------------------------------------------------------------\n",
    "KeyError                                  Traceback (most recent call last)\n",
    "<ipython-input-9-c0115ca8d9b5> in <module>()\n",
    "----> 1 Out[6]\n",
    "\n",
    "KeyError: 6\n",
    "```\n",
    "**粘贴**    IPython支持多种格式的粘贴，除了`%paste`魔法方法，还可以直接粘贴多行代码、doctest代码和IPython的代码，举例如下（下面的代码都是使用`ctrl+v`直接粘贴的，如果是linux终端，那么应该使用`ctrl+shift+v`直接粘贴，或者单击鼠标右键，选择“粘贴”选项）。\n",
    "\n",
    "```python\n",
    "In [1]: In [1]: import torch as t\n",
    "   ...: \n",
    "   ...: In [2]: a=t.Tensor(5,5)\n",
    "   ...: \n",
    "   ...: In [3]: a\n",
    "   ...: \n",
    "Out[1]: \n",
    "\n",
    "1.00000e-33 *\n",
    " -1.0299  0.0000  0.0001  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "[torch.FloatTensor of size 5x5]\n",
    "\n",
    "In [2]: >>> import torch as t\n",
    "   ...: >>> a=t.Tensor(5,5)\n",
    "   ...: >>> a\n",
    "   ...: \n",
    "Out[2]: \n",
    "\n",
    "1.00000e-33 *\n",
    " -1.0298  0.0000 -1.0298  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "[torch.FloatTensor of size 5x5]\n",
    "\n",
    "In [3]: import torch as t\n",
    "   ...: a = t.Tensor(5,5)\n",
    "   ...: a\n",
    "   ...: \n",
    "Out[3]: \n",
    "\n",
    "1.00000e-33 *\n",
    " -1.0298  0.0000 -1.0298  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "  0.0000  0.0000  0.0000  0.0000  0.0000\n",
    "[torch.FloatTensor of size 5x5]\n",
    "```\n",
    "\n",
    "**使用IPython进行调试**    IPython的调试器ipdb增强了pdb，提供了很多实用功能，例如Tab键自动补全、语法高亮等。在IPython中进入pdb的最快速方式是使用魔术命令%debug，此时用户能够直接调到报错的代码处，可通过u、d实现堆栈中的上下移动，常用的调试命令如表2-3所示。\n",
    "\n",
    "表2-3: ipdb常用调试命令\n",
    "\n",
    "|  命令   |                       功能                       |\n",
    "| :-----: | :----------------------------------------------: |\n",
    "| h(elp)  | 显示帮助信息，help command显示这条命令的帮助信息 |\n",
    "|  u(p)   |              在函数调用栈中向上移动              |\n",
    "| d(own)  |              在函数调用栈中向下移动              |\n",
    "| n(ext)  |               单歩执行，执行下一步               |\n",
    "| s(tep)  |               单歩进入当前函数调用               |\n",
    "| a(rgs)  |              查看当前调用函数的参数              |\n",
    "| l(ist)  |            查看当前行的上下文参考代码            |\n",
    "| b(reak) |               在指定位置上设置断点               |\n",
    "| q(uit)  |                       退出                       |\n",
    "\n",
    "debug是一个重要功能，不仅在学习PyTorch时需要用到，在平时学习Python或使用IPython时也会经常使用。更多的debug功能，可通过`h <命令>`查看该命令的使用方法。\n",
    "\n",
    "如果想在IPython之外使用debug功能，则需安装ipdb(pip install ipdb)，而后在需要进入调试的地方加上如下代码即可。\n",
    "\n",
    "```python\n",
    "import ipdb\n",
    "ipdb.set_trace()\n",
    "```\n",
    "\n",
    "此时当程序运行到这一步的时候，会自动进入debug模式。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Jupyter Notebook\n",
    "\n",
    "Jupyter Notebook是一个交互式笔记本，前身是IPython Notebook，后从IPython中独立出来，现支持运行40多种编程语言。对于希望编写漂亮的交互式文档和从事科学计算的用户来说是一个不错的选择。\n",
    "\n",
    "Jupyter Notebook的使用方法与IPython非常类似，推荐使用Jupyter Notebook主要有如下三个原因。\n",
    "\n",
    "- 更美观的界面：相比在终端下使用IPython，Notebook提供图形化操作界面，对新手而言更美观简洁；\n",
    "- 更好的可视化支持：Notebook与Web技术深度融合，支持在Notebook中直接可视化，这对于需要经常绘图的科学运算实验来说很方便；\n",
    "- 方便远程访问：在服务器端开启Notebook服务后，客户端电脑只需有浏览器且能访问服务器，即可使用远程服务器上的Notebook，这对于很多使用Linux服务器，但工作电脑使用Windows的人来说十分方便，避免了在本地配置环境的复杂流程。\n",
    "\n",
    "安装Jupyter只需一条pip命令。\n",
    "\n",
    "```bash\n",
    "pip install jupyter   \n",
    "```\n",
    "\n",
    "安装完成后，在命令行输入`jupyter notebook`命令即可启动Jupyter，此时浏览器会自动弹出，并打开Jupyter主界面，也可手动打开浏览器，输入`http://127.0.0.1:8888`访问Jupyter，界面如图2-9所示。\n",
    "\n",
    "![图2-9  Notebook主界面](imgs/Notebook主界面.png)\n",
    "\n",
    "点击右上角的new，选择相应的Notebook类型(Python3/Python2)，即可新建一个Notebook。读者可以在在In[]后面的编辑区输入代码，按Ctrl+Enter键，即可运行代码，如图2-10所示。\n",
    "\n",
    "![图2-10  Notebook中运行代码](imgs/Notebook中运行代码.png)\n",
    "\n",
    "\n",
    "\n",
    "对于远程访问服务器Jupyter的用户，需要在服务器中搭建Jupyter Notebook服务，而后通过浏览器访问。其设置流程如下：\n",
    "\n",
    "1. 生成Jupyter的配置文件。\n",
    "\n",
    "```\n",
    "jupyter notebook --generate-config\n",
    "```\n",
    "2. 设置密码，并获取加密后的密码。\n",
    "\n",
    "```python\n",
    "from notebook.auth import passwd\n",
    "\n",
    "p = passwd()\n",
    "# 输入密码\n",
    "# 确认密码\n",
    "print(p)\n",
    "```\n",
    "\n",
    "打印得到的结果`argon2:...` 即为加密后的密码。\n",
    "3. 打开第一步生成的配置文件，修改以下内容。\n",
    "\n",
    "```python\n",
    "# 加密后的密码\n",
    "c.NotebookApp.password = u'argon2:...' \n",
    "\n",
    "# 如果只想绑定某个ip，改成对应的ip即可\n",
    "c.NotebookApp.ip = '*'\n",
    "\n",
    "# 绑定的端口号，如果该端口已经被占用，\n",
    "# 会自动使用下一个端口号10000\n",
    "c.NotebookApp.port = 9999 \n",
    "```\n",
    "\n",
    "4. 启动Jupyter Notebook。\n",
    "\n",
    "```bash\n",
    "jupyter notebook\n",
    "```\n",
    "\n",
    "5. 在客户端打开浏览器，访问url http://[服务器ip]:9999 ，输入密码，即可访问Jupyter。\n",
    "\n",
    "若客户端浏览器无法打开Jupyter，则可能是防火墙的缘故，输入如下命令开放对应的端口(若使用IPV6，把命令`iptables`改成`ip6tables`)。\n",
    "\n",
    "```bash\n",
    "iptables -I INPUT -p tcp --dport 9999 -j ACCEPT\n",
    "iptables save\n",
    "```\n",
    "\n",
    "Jupyter的使用和IPython极为类似，我们之前介绍的IPython的使用技巧在Jupyter中也都基本适用。它支持自动补全、内省、魔术方法和debug功能等，但它的快捷键与IPython有较大不同，具体可通过菜单栏的【Help】->【Keyboard Shortcuts】查看。\n",
    "\n",
    "Jupyter还支持很多功能，如Markdown语法、HTML、各种可视化等。读者可在网络上寻找更多有关IPython和Jupyter Notebook的使用技巧。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.2 PyTorch入门第一步\n",
    "\n",
    "PyTorch的简洁设计使得它易于入门，在深入介绍PyTorch之前，本节将先介绍一些PyTorch的基础知识，以便读者能够对PyTorch有一个大致的了解，并能够用PyTorch搭建一个简单的神经网络。对于其中的部分内容读者可能暂时不太理解，可先不予深究，本书的第3至5章将会对这些内容进行深入讲解。\n",
    "\n",
    "本节内容参考了PyTorch官方教程并做了相应的增删，使得内容更贴合新版本的PyTorch接口，同时也更适合新手快速入门。另外，本书需要读者先掌握基础的Numpy使用，有关NumPy的基础知识可以参考CS231n的教程。\n",
    "\n",
    "\n",
    "### 2.2.1 Tensor\n",
    "\n",
    "Tensor是PyTorch中重要的数据结构，可以认为是一个高维数组。它可以是一个数（标量）、一维数组（向量）、二维数组（矩阵）或者更高维的数组。Tensor和Numpy的ndarrays类似，但Tensor可以使用GPU加速。Tensor的使用和Numpy十分相似，下面通过几个示例来了解Tensor的基本使用方法。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'1.6.0'"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import torch as t\n",
    "t.__version__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.0000e+00, 0.0000e+00, 1.4013e-45],\n",
       "        [0.0000e+00, 1.4013e-45, 0.0000e+00],\n",
       "        [0.0000e+00, 0.0000e+00, 2.8026e-45],\n",
       "        [1.4013e-45, 8.7212e-36, 4.5843e-41],\n",
       "        [0.0000e+00, 0.0000e+00, 0.0000e+00]])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 构建 5x3 矩阵，只是分配了空间，未初始化，其数值取决于内存空间的状态\n",
    "x = t.Tensor(5, 3) #维度：5*3\n",
    "x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "torch.Tensor可以使用int类型的整数用于初始化矩阵的行、列数，并且不存在任何歧义。而torch.tensor则需要确切的数据值进行初始化。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([5])\n",
      "torch.Size([1])\n"
     ]
    }
   ],
   "source": [
    "y = t.Tensor(5)\n",
    "print(y.size())\n",
    "z = t.tensor([5])# torch.tensor需要确切数值进行初始化\n",
    "print(z.size())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.8520, 0.8969, 0.1491],\n",
       "        [0.2160, 0.7502, 0.4543],\n",
       "        [0.1314, 0.7583, 0.3892],\n",
       "        [0.3490, 0.3251, 0.2462],\n",
       "        [0.9337, 0.2864, 0.5309]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用[0,1]均匀分布随机初始化二维数组\n",
    "x = t.rand(5, 3)  \n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([5, 3])\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(3, 3)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(x.shape) # 查看x的形状\n",
    "x.size()[1], x.size(1) # 查看列的个数, 两种写法等价"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1.0933, 0.9650, 0.9577],\n",
       "        [0.8297, 1.6523, 1.0367],\n",
       "        [0.7512, 1.4044, 0.9851],\n",
       "        [1.2323, 0.7215, 0.4068],\n",
       "        [1.8066, 0.4495, 1.0121]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = t.rand(5, 3)\n",
    "# 加法的第一种写法\n",
    "x + y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1.0933, 0.9650, 0.9577],\n",
       "        [0.8297, 1.6523, 1.0367],\n",
       "        [0.7512, 1.4044, 0.9851],\n",
       "        [1.2323, 0.7215, 0.4068],\n",
       "        [1.8066, 0.4495, 1.0121]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 加法的第二种写法\n",
    "t.add(x, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1.0933, 0.9650, 0.9577],\n",
       "        [0.8297, 1.6523, 1.0367],\n",
       "        [0.7512, 1.4044, 0.9851],\n",
       "        [1.2323, 0.7215, 0.4068],\n",
       "        [1.8066, 0.4495, 1.0121]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 加法的第三种写法：指定加法结果的输出目标为result\n",
    "result = t.Tensor(5, 3) # 预先分配空间\n",
    "# result = torch.empty(5,3)\n",
    "t.add(x, y, out=result) # 输入到result\n",
    "result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "初始的y值\n",
      "tensor([[0.2413, 0.0681, 0.8086],\n",
      "        [0.6137, 0.9021, 0.5824],\n",
      "        [0.6199, 0.6461, 0.5960],\n",
      "        [0.8833, 0.3964, 0.1606],\n",
      "        [0.8729, 0.1632, 0.4812]])\n",
      "第一种加法，y的结果\n",
      "tensor([[0.2413, 0.0681, 0.8086],\n",
      "        [0.6137, 0.9021, 0.5824],\n",
      "        [0.6199, 0.6461, 0.5960],\n",
      "        [0.8833, 0.3964, 0.1606],\n",
      "        [0.8729, 0.1632, 0.4812]])\n",
      "第二种加法，y的结果\n",
      "tensor([[1.0933, 0.9650, 0.9577],\n",
      "        [0.8297, 1.6523, 1.0367],\n",
      "        [0.7512, 1.4044, 0.9851],\n",
      "        [1.2323, 0.7215, 0.4068],\n",
      "        [1.8066, 0.4495, 1.0121]])\n"
     ]
    }
   ],
   "source": [
    "print('初始的y值')\n",
    "print(y)\n",
    "\n",
    "print('第一种加法，y的结果')\n",
    "y.add(x) # 普通加法，不改变y的内容\n",
    "print(y)\n",
    "\n",
    "print('第二种加法，y的结果')\n",
    "y.add_(x) # inplace 加法，y变了\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "注意，函数名后面带下划线**`_`** 的函数会修改Tensor本身，即inplace操作。例如，`x.add_(y)`和`x.t_()`会改变 `x`，但`x.add(y)`和`x.t()`返回一个新的Tensor，而`x`不变。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([0.8969, 0.7502, 0.7583, 0.3251, 0.2864])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Tensor的选取操作与Numpy类似\n",
    "x[:, 1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tensor还支持很多操作，包括数学运算、线性代数、选择、切片等等，其接口设计与Numpy极为相似。在第三章中我们将系统讲解Tensor更详细的使用方法。\n",
    "\n",
    "Tensor和NumPy的数组之间的相互操作非常容易且快速。对于Tensor不支持的操作，可以先转为Numpy数组处理，之后再转回Tensor。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([1., 1., 1., 1., 1.])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = t.ones(5) # 新建一个全1的Tensor\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1., 1., 1., 1., 1.], dtype=float32)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = a.numpy() # Tensor -> Numpy\n",
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1. 1. 1. 1. 1.]\n",
      "tensor([1., 1., 1., 1., 1.], dtype=torch.float64)\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "a = np.ones(5)\n",
    "b = t.from_numpy(a) # Numpy->Tensor\n",
    "print(a)\n",
    "print(b) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tensor和NumPy对象共享内存，所以它们之间的转换很快，而且几乎不会消耗什么资源。但这也意味着，如果其中一个发生了变化，另外一个会随之改变。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2. 2. 2. 2. 2.]\n",
      "tensor([2., 2., 2., 2., 2.], dtype=torch.float64)\n"
     ]
    }
   ],
   "source": [
    "b.add_(1) # 以`_`结尾的函数会修改自身\n",
    "print(a)\n",
    "print(b) # Tensor和Numpy共享内存"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果你想获取某一个元素的值，可以使用`scalar.item`。 直接`tensor[idx]`得到的还是一个tensor: 一个0-dim 的tensor，一般称为scalar。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor(2., dtype=torch.float64)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "scalar = b[0]\n",
    "scalar"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "scalar.shape #0-dim "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.0"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "scalar.item() # 使用scalar.item()能从中取出python对象的数值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([2]), tensor(2., dtype=torch.float64))"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tensor = t.tensor([2]) # 注意和scalar的区别\n",
    "tensor,scalar"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(torch.Size([1]), torch.Size([]))"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tensor.size(),scalar.size()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2, 2.0)"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 只有一个元素的tensor也可以调用`tensor.item()`\n",
    "tensor.item(), scalar.item()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "tensor = t.tensor([3,4]) # 新建一个包含 3，4 两个元素的tensor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor(3)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "scalar = t.tensor(3)\n",
    "scalar"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([3, 4]), tensor([1111,    4]))"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "old_tensor = tensor\n",
    "new_tensor = old_tensor.clone()\n",
    "new_tensor[0] = 1111\n",
    "old_tensor, new_tensor"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "需要注意的是，`t.tensor()`或者`tensor.clone()`总是会进行数据拷贝，新Tensor和原来的数据不再共享内存。所以如果你想共享内存的话，建议使用`torch.from_numpy()`或者`tensor.detach()`来新建一个Tensor, 二者共享内存。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在深度学习中，Tensor作为一种最基础的数据容器，其维度特征十分重要，而有时我们需要对其进行维度上的转换或者变换，针对该问题，PyTorch提供了许多非常便利的转换方式：包括维度变换view、reshape、维度交换permute以及transpose等。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "首先来看维度变换操作，我们可以使用`view`操作与`reshape`操作来改变Tensor的维度，但它们二值之间有一些区别：\n",
    "\n",
    "1. `view`只能用于内存中连续存储的Tensor，即：若对Tensor使用过`transpose`、`permute`等维度变换操作的话，会使得Tensor在内存中变得不连续，此时就便不能直接使用`view`操作，而应该先将其连续化，即`tensor.contiguous.view()`；\n",
    "\n",
    "2. 而对于`reshape`操作，其并不要求Tensor在内存中是连续的，直接使用即可。\n",
    "\n",
    "下面将举例说明。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])\n"
     ]
    }
   ],
   "source": [
    "x = t.randn(4,4)\n",
    "y = x.view(16)\n",
    "z = x.view(-1,8) #-1表示由其他维度计算决定\n",
    "print(x.size(),y.size(),z.size())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([2, 8])\n"
     ]
    }
   ],
   "source": [
    "p = x.reshape(-1,8)\n",
    "print(p.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "o1 sizetorch.Size([6, 4, 2])\n",
      "o2 sizetorch.Size([6, 4, 2])\n",
      "o2 size torch.Size([6, 4, 2])\n"
     ]
    }
   ],
   "source": [
    "x1 = t.randn(2,4,6)\n",
    "o1 = x1.permute((2,1,0))\n",
    "o2 = x1.transpose(0,2)\n",
    "print(f'o1 size{o1.size()}')\n",
    "print(f'o2 size{o2.size()}')\n",
    "print(f'o2 size {o2.size()}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([1111,    4]), tensor([1111,    4]))"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "new_tensor = old_tensor.detach()\n",
    "new_tensor[0] = 1111\n",
    "old_tensor, new_tensor"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "除了对Tensor进行维度变换外，我们还会针对Tensor的某些维度进行一些其他操作，如`tensor.squeeze()`可以进行Tensor的维度压缩、`tensor.unsqueeze()`可以扩展Tensor的维度、`torch.cat()`可以在指定维度上进行Tensor的拼接，下面将举例说明。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "y sizetorch.Size([3, 2, 1])\n",
      "z sizetorch.Size([1, 3, 2, 1, 1])\n",
      "w sizetorch.Size([6, 2, 1, 1])\n"
     ]
    }
   ],
   "source": [
    "x = t.randn(3,2,1,1)\n",
    "y = x.squeeze(-1) #将最后一维进行维度压缩\n",
    "z = x.unsqueeze(0) #在第一维度增加一个维度\n",
    "w = t.cat((x,x),0) #在第一维度连接两个x\n",
    "print(f'y size{y.shape}')\n",
    "print(f'z size{z.shape}')\n",
    "print(f'w size{w.shape}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果有一个仅含有一个元素的Tensor，可以使用`.item()`来获得其数值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([-0.5549])\n",
      "-0.5549378395080566\n"
     ]
    }
   ],
   "source": [
    "x = t.randn(1)\n",
    "print(x)\n",
    "print(x.item())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 在不支持CUDA的机器下，下一步还是在CPU上运行\n",
    "device = t.device(\"cuda:0\" if t.cuda.is_available() else \"cpu\")\n",
    "x = x.to(device)\n",
    "y = y.to(x.device)\n",
    "z = x+y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "此外，还可以使用`tensor.cuda()` 的方式将tensor拷贝到gpu上，但是这种方式不太推荐。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "此处可能发现GPU运算的速度并未提升太多，这是因为x和y太小且运算也较为简单，而且将数据从内存转移到显存还需要花费额外的开销。GPU的优势需在大规模数据和复杂运算下才能体现出来。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "### 2.2.2 Autograd: 自动微分\n",
    "\n",
    "\n",
    "在深度学习中，我们通常使用梯度下降法来最小化损失函数，以此来更新网络参数。在神经网络中梯度下降法的实现便是通过反向传播求导数，PyTorch中的autograd模块便实现了自动的反向传播功能。在Tensor上的所有操作，autograd都能为它们自动提供微分，避免了手动计算导数的复杂过程。\n",
    "要想使得Tensor使用autograd功能，只需要设置`tensor.requries_grad=True`即可。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1., 1.],\n",
       "        [1., 1.]], requires_grad=True)"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 为Tensor设置requires_grad标识，代表着需要求导数\n",
    "# PyTorch 会自动调用autograd记录操作\n",
    "x = t.ones(2, 2, requires_grad=True)\n",
    "\n",
    "# 上一步等价于\n",
    "# x = t.ones(2,2)\n",
    "# x.requires_grad = True\n",
    "\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor(4., grad_fn=<SumBackward0>)"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = x.sum()\n",
    "y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<SumBackward0 at 0x7fca878c8748>"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.grad_fn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "y.backward() # 反向传播,计算梯度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1., 1.],\n",
       "        [1., 1.]])"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# y = x.sum() = (x[0][0] + x[0][1] + x[1][0] + x[1][1])\n",
    "# 每个值的梯度都为1\n",
    "x.grad "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "注意：`grad`在反向传播过程中是累加的(accumulated)，这意味着每一次运行反向传播，梯度都会累加之前的梯度，所以反向传播之前需把梯度清零。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[2., 2.],\n",
       "        [2., 2.]])"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.backward()\n",
    "x.grad"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[3., 3.],\n",
       "        [3., 3.]])"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.backward()\n",
    "x.grad"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0., 0.],\n",
       "        [0., 0.]])"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 以下划线结束的函数是inplace操作，会修改自身的值，就像add_\n",
    "x.grad.data.zero_()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[1., 1.],\n",
       "        [1., 1.]])"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y.backward()\n",
    "x.grad"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n",
      "<SumBackward0 object at 0x7fca87873128>\n"
     ]
    }
   ],
   "source": [
    "a = t.randn(2,2)\n",
    "a = ((a*3)/(a-1))\n",
    "print(a.requires_grad)\n",
    "a.requires_grad_(True)\n",
    "print(a.requires_grad)\n",
    "b = (a*a).sum()\n",
    "print(b.grad_fn)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###  2.2.3 神经网络\n",
    "\n",
    "autograd实现了自动微分系统，但在很多情况下直接用来写深度学习的代码还是稍显复杂。torch.nn是专门为神经网络设计的模块化接口。nn构建于autograd之上，可用来定义和运行神经网络。nn.Module是nn中最重要的类，可把它看成是一个网络的封装，包含网络各层定义以及forward方法，调用forward(input)方法，可返回前向传播的结果。下面就以最早的卷积神经网络：LeNet为例，来看看如何用`nn.Module`实现。LeNet的网络结构如图2-11所示。\n",
    "\n",
    "![图2-11:LeNet网络结构](imgs/nn_lenet.png)\n",
    "\n",
    "对于一个神经网络而言，其通用的训练步骤如下：\n",
    "\n",
    "1. 定义一个包含可学习参数的神经网络；\n",
    "2. 加载输入至网络的数据集；\n",
    "3. 进行前向传播得到网络的输出结果，并计算损失（网络输出结果与正确结果的差距）；\n",
    "4. 进行反向传播，更新网络参数，其中更新策略中最简单的方式即`weight=weight-learning_rate*gradient`；\n",
    "5. 保存网络模型。\n",
    "\n",
    "#### 定义网络\n",
    "\n",
    "定义网络时，需要继承`nn.Module`，并实现它的forward方法，把网络中具有可学习参数的层放在构造函数`__init__`中。如果某一层(如ReLU)不具有可学习的参数，则既可以放在构造函数中，也可以不放，但笔者建议不放在其中，而在forward中使用`nn.functional`代替。下面将举例说明。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Net(\n",
      "  (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))\n",
      "  (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))\n",
      "  (fc1): Linear(in_features=400, out_features=120, bias=True)\n",
      "  (fc2): Linear(in_features=120, out_features=84, bias=True)\n",
      "  (fc3): Linear(in_features=84, out_features=10, bias=True)\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "class Net(nn.Module):\n",
    "    def __init__(self):\n",
    "        # nn.Module子类的函数必须在构造函数中执行父类的构造函数\n",
    "        # 下式等价于nn.Module.__init__(self)\n",
    "        super(Net, self).__init__()\n",
    "        \n",
    "        # 卷积层 '1'表示输入图片为单通道, '6'表示输出通道数，'5'表示卷积核为5*5\n",
    "        self.conv1 = nn.Conv2d(1, 6, 5) \n",
    "        # 卷积层\n",
    "        self.conv2 = nn.Conv2d(6, 16, 5) \n",
    "        # 仿射层/全连接层，y = Wx + b\n",
    "        self.fc1   = nn.Linear(16*5*5, 120) \n",
    "        self.fc2   = nn.Linear(120, 84)\n",
    "        self.fc3   = nn.Linear(84, 10)\n",
    "\n",
    "    def forward(self, x): \n",
    "        # 卷积 -> 激活 -> 池化 \n",
    "        \n",
    "        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))\n",
    "        x = F.max_pool2d(F.relu(self.conv2(x)), 2) \n",
    "        # reshape，‘-1’表示自适应\n",
    "        x = x.view(x.size()[0], -1) \n",
    "        x = F.relu(self.fc1(x))\n",
    "        x = F.relu(self.fc2(x))\n",
    "        x = self.fc3(x)        \n",
    "        return x\n",
    "\n",
    "net = Net()\n",
    "print(net)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "只要在nn.Module的子类中定义了forward函数，backward函数就会自动被实现(利用autograd)。在forward函数中可使用任何Tensor支持的函数，还可以使用if、for循环、print、log等Python语法，写法和标准的Python写法一致。\n",
    "\n",
    "网络的可学习参数通过`net.parameters()`返回，`net.named_parameters`可同时返回可学习的参数及名称。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10\n"
     ]
    }
   ],
   "source": [
    "params = list(net.parameters())\n",
    "print(len(params))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "conv1.weight : torch.Size([6, 1, 5, 5])\n",
      "conv1.bias : torch.Size([6])\n",
      "conv2.weight : torch.Size([16, 6, 5, 5])\n",
      "conv2.bias : torch.Size([16])\n",
      "fc1.weight : torch.Size([120, 400])\n",
      "fc1.bias : torch.Size([120])\n",
      "fc2.weight : torch.Size([84, 120])\n",
      "fc2.bias : torch.Size([84])\n",
      "fc3.weight : torch.Size([10, 84])\n",
      "fc3.bias : torch.Size([10])\n"
     ]
    }
   ],
   "source": [
    "for name,parameters in net.named_parameters():\n",
    "    print(name,':',parameters.size())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([1, 10])"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "input = t.randn(1, 1, 32, 32)\n",
    "out = net(input)\n",
    "out.size()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [],
   "source": [
    "net.zero_grad() # 所有参数的梯度清零\n",
    "out.backward(t.ones(1,10)) # 反向传播"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "需要注意的是，torch.nn只支持mini-batches，不支持一次只输入一个样本，而必须是一个batch。但如果只想输入一个样本，则用 `input.unsqueeze(0)`将batch_size设为１。例如 `nn.Conv2d` 输入必须是4维的，形如$nSamples \\times nChannels \\times Height \\times Width$。可将nSample设为1，即$1 \\times nChannels \\times Height \\times Width$。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 损失函数\n",
    "\n",
    "nn实现了神经网络中大多数的损失函数，例如nn.MSELoss用来计算均方误差，nn.CrossEntropyLoss用来计算交叉熵损失。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor(28.1249, grad_fn=<MseLossBackward>)"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "output = net(input)\n",
    "target = t.arange(0,10).view(1,10).float() \n",
    "criterion = nn.MSELoss()\n",
    "loss = criterion(output, target)\n",
    "loss # loss是个scalar"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果对loss进行反向传播溯源(使用`gradfn`属性)，可看到它的计算图如下：\n",
    "\n",
    "```\n",
    "input -> conv2d -> relu -> maxpool2d -> conv2d -> relu -> maxpool2d  \n",
    "      -> view -> linear -> relu -> linear -> relu -> linear \n",
    "      -> MSELoss\n",
    "      -> loss\n",
    "```\n",
    "\n",
    "当调用`loss.backward()`时，该图会动态生成并自动微分，也即会自动计算图中参数(Parameter)的导数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "反向传播之前 conv1.bias的梯度\n",
      "tensor([0., 0., 0., 0., 0., 0.])\n",
      "反向传播之后 conv1.bias的梯度\n",
      "tensor([ 0.0020, -0.0619,  0.1077,  0.0197,  0.1027, -0.0060])\n"
     ]
    }
   ],
   "source": [
    "# 运行.backward，观察调用之前和调用之后的grad\n",
    "net.zero_grad() # 把net中所有可学习参数的梯度清零\n",
    "print('反向传播之前 conv1.bias的梯度')\n",
    "print(net.conv1.bias.grad)\n",
    "loss.backward()\n",
    "print('反向传播之后 conv1.bias的梯度')\n",
    "print(net.conv1.bias.grad)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 优化器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在反向传播计算完所有参数的梯度后，还需要使用优化方法来更新网络的权重和参数，如随机梯度下降法(SGD)的更新策略如下：\n",
    "```\n",
    "weight = weight - learning_rate * gradient\n",
    "```\n",
    "\n",
    "我们可以手动实现这一更新策略：\n",
    "\n",
    "```python\n",
    "learning_rate = 0.01\n",
    "for f in net.parameters():\n",
    "    f.data.sub_(f.grad.data * learning_rate)# inplace 减法\n",
    "```\n",
    "\n",
    "`torch.optim`中实现了深度学习中绝大多数的优化方法，例如RMSProp、Adam、SGD等，更便于使用，因此读者通常并不需要手动实现上述代码。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch.optim as optim\n",
    "#新建一个优化器，指定要调整的参数和学习率\n",
    "optimizer = optim.SGD(net.parameters(), lr = 0.01)\n",
    "\n",
    "# 在训练过程中\n",
    "# 先梯度清零(与net.zero_grad()效果一样)\n",
    "optimizer.zero_grad() \n",
    "\n",
    "# 计算损失\n",
    "output = net(input)\n",
    "loss = criterion(output, target)\n",
    "\n",
    "#反向传播\n",
    "loss.backward()\n",
    "\n",
    "#更新参数\n",
    "optimizer.step()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "####  数据加载与预处理\n",
    "\n",
    "在深度学习中数据加载及预处理是非常复杂繁琐的，但PyTorch提供了一些可极大简化和加快数据处理流程的工具。同时，对于常用的数据集，PyTorch也提供了封装好的接口供用户快速调用，这些数据集主要保存在torchvison中。\n",
    "\n",
    "torchvision是一个视觉工具包，其中提供了许多视觉图像处理的工具。torchvision主要包含三大部分：\n",
    "1. datasets：提供了常用的数据集，如MNIST、CIFAR10及ImageNet等；\n",
    "2. models：提供了深度学习中经典的网络结构与预训练模型，如ResNet、MobileNet等；\n",
    "3. transforms：提供了常用的数据预处理操作，主要包括对Tensor、PIL Image等的操作；\n",
    "\n",
    "我们可以使用torchvision方便地加载数据，并对其进行处理，这部分内容将在本书第五章进行详细介绍。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2.4 小试牛刀：CIFAR-10分类\n",
    "\n",
    "下面我们来尝试实现对CIFAR-10数据集的分类，步骤如下: \n",
    "\n",
    "1. 使用torchvision加载并预处理CIFAR-10数据集；\n",
    "2. 定义网络；\n",
    "3. 定义损失函数和优化器；\n",
    "4. 训练网络(更新网络参数)；\n",
    "5. 测试网络。\n",
    "\n",
    "####   CIFAR-10数据加载及预处理\n",
    "\n",
    "CIFAR-10是一个常用的彩色图片数据集，它有10个类别: 'airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'。每张图片都是$3\\times32\\times32$，也即3-通道彩色图片，分辨率为$32\\times32$。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch as t\n",
    "import torchvision as tv\n",
    "import torchvision.transforms as transforms\n",
    "from torchvision.transforms import ToPILImage\n",
    "show = ToPILImage() # 可以把Tensor转成Image，方便可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Files already downloaded and verified\n",
      "Files already downloaded and verified\n"
     ]
    }
   ],
   "source": [
    "# 第一次运行程序torchvision会自动下载CIFAR-10数据集，\n",
    "# 大约100M，需花费一定的时间，\n",
    "# 如果已经下载有CIFAR-10，可通过root参数指定\n",
    "\n",
    "# 定义对数据的预处理\n",
    "transform = transforms.Compose([\n",
    "        transforms.ToTensor(), # 转为Tensor\n",
    "        transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)), # 归一化\n",
    "                             ])\n",
    "\n",
    "# 训练集\n",
    "trainset = tv.datasets.CIFAR10(\n",
    "                    root='./pytorch-book-cifar10/', \n",
    "                    train=True, \n",
    "                    download=True,\n",
    "                    transform=transform)\n",
    "\n",
    "trainloader = t.utils.data.DataLoader(\n",
    "                    trainset, \n",
    "                    batch_size=4,\n",
    "                    shuffle=True, \n",
    "                    num_workers=2)\n",
    "\n",
    "# 测试集\n",
    "testset = tv.datasets.CIFAR10(\n",
    "                    './pytorch-book-cifar10/',\n",
    "                    train=False, \n",
    "                    download=True, \n",
    "                    transform=transform)\n",
    "\n",
    "testloader = t.utils.data.DataLoader(\n",
    "                    testset,\n",
    "                    batch_size=4, \n",
    "                    shuffle=False,\n",
    "                    num_workers=2)\n",
    "\n",
    "classes = ('plane', 'car', 'bird', 'cat',\n",
    "           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Dataset对象是一个数据集，可以按下标访问，返回形如(data, label)的数据。\n",
    "Dataset通过调用其中的```__getitem__```返回相应数据 \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ship\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<PIL.Image.Image image mode=RGB size=100x100 at 0x7FCA127B6C88>"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(data, label) = trainset[100]\n",
    "print(classes[label])\n",
    "\n",
    "# (data + 1) / 2是为了还原被归一化的数据\n",
    "show((data + 1) / 2).resize((100, 100))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Dataloader是一个可迭代的对象，它将Dataset返回的每一条数据样本拼接成一个batch，并提供多线程加速优化和数据打乱等操作。当程序对Dataset的所有数据遍历完一遍之后，对Dataloader也完成了一次迭代。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "      horse        frog       plane        bird\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<PIL.Image.Image image mode=RGB size=400x100 at 0x7FCA125E81D0>"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataiter = iter(trainloader)\n",
    "images, labels = dataiter.next() # 返回4张图片及标签\n",
    "print(' '.join('%11s'%classes[labels[j]] for j in range(4)))\n",
    "show(tv.utils.make_grid((images+1)/2)).resize((400,100))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "####   定义网络\n",
    "\n",
    "拷贝上面的LeNet网络，修改self.conv1第一个参数为3通道，因CIFAR-10是3通道彩图。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Net(\n",
      "  (conv1): Conv2d(3, 6, kernel_size=(5, 5), stride=(1, 1))\n",
      "  (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))\n",
      "  (fc1): Linear(in_features=400, out_features=120, bias=True)\n",
      "  (fc2): Linear(in_features=120, out_features=84, bias=True)\n",
      "  (fc3): Linear(in_features=84, out_features=10, bias=True)\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "class Net(nn.Module):\n",
    "    def __init__(self):\n",
    "        super(Net, self).__init__()\n",
    "        self.conv1 = nn.Conv2d(3, 6, 5) \n",
    "        self.conv2 = nn.Conv2d(6, 16, 5)  \n",
    "        self.fc1   = nn.Linear(16*5*5, 120)  \n",
    "        self.fc2   = nn.Linear(120, 84)\n",
    "        self.fc3   = nn.Linear(84, 10)\n",
    "\n",
    "    def forward(self, x): \n",
    "        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2)) \n",
    "        x = F.max_pool2d(F.relu(self.conv2(x)), 2) \n",
    "        x = x.view(x.size()[0], -1) \n",
    "        x = F.relu(self.fc1(x))\n",
    "        x = F.relu(self.fc2(x))\n",
    "        x = self.fc3(x)        \n",
    "        return x\n",
    "\n",
    "\n",
    "net = Net()\n",
    "print(net)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "####  定义损失函数和优化器(loss和optimizer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [],
   "source": [
    "from torch import optim\n",
    "criterion = nn.CrossEntropyLoss() # 交叉熵损失函数\n",
    "optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "####   训练网络\n",
    "\n",
    "所有网络的训练流程都是类似的，也就是不断地执行如下流程：\n",
    "\n",
    "- 输入数据；\n",
    "- 前向传播+反向传播；\n",
    "- 更新参数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1,  2000] loss: 2.228\n",
      "[1,  4000] loss: 1.890\n",
      "[1,  6000] loss: 1.683\n",
      "[1,  8000] loss: 1.592\n",
      "[1, 10000] loss: 1.513\n",
      "[1, 12000] loss: 1.478\n",
      "[2,  2000] loss: 1.387\n",
      "[2,  4000] loss: 1.368\n",
      "[2,  6000] loss: 1.346\n",
      "[2,  8000] loss: 1.324\n",
      "[2, 10000] loss: 1.300\n",
      "[2, 12000] loss: 1.255\n",
      "Finished Training\n"
     ]
    }
   ],
   "source": [
    "for epoch in range(2):  \n",
    "    \n",
    "    running_loss = 0.0\n",
    "    for i, data in enumerate(trainloader, 0):\n",
    "        \n",
    "        # 输入数据\n",
    "        inputs, labels = data\n",
    "        \n",
    "        # 梯度清零\n",
    "        optimizer.zero_grad()\n",
    "        \n",
    "        # forward + backward \n",
    "        outputs = net(inputs)\n",
    "        loss = criterion(outputs, labels)\n",
    "        loss.backward()   \n",
    "        \n",
    "        # 更新参数 \n",
    "        optimizer.step()\n",
    "        \n",
    "        # 打印log信息\n",
    "        # loss 是一个scalar, 要使用loss.item()来获取数值，不能使用loss[0]\n",
    "        running_loss += loss.item()\n",
    "        if i % 2000 == 1999: # 每2000个batch打印一下训练状态\n",
    "            print('[%d, %5d] loss: %.3f' \\\n",
    "                  % (epoch+1, i+1, running_loss / 2000))\n",
    "            running_loss = 0.0\n",
    "print('Finished Training')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "此处仅训练了2个epoch（遍历完一遍数据集称为一个epoch），我们来看看网络有没有效果。将测试图片输入到网络中，计算它的label，然后与实际的label进行比较。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "实际的label:       cat     ship     ship    plane\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<PIL.Image.Image image mode=RGB size=400x100 at 0x7FCA127B6588>"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataiter = iter(testloader)\n",
    "images, labels = dataiter.next() # 一个batch返回4张图片\n",
    "print('实际的label: ', ' '.join(\\\n",
    "            '%08s'%classes[labels[j]] for j in range(4)))\n",
    "show(tv.utils.make_grid(images / 2 - 0.5)).resize((400,100))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接着计算网络预测的label："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "预测结果:    cat  ship  ship  ship\n"
     ]
    }
   ],
   "source": [
    "# 计算图片在每个类别上的分数\n",
    "outputs = net(images)\n",
    "# 得分最高的那个类\n",
    "_, predicted = t.max(outputs.data, 1)\n",
    "\n",
    "print('预测结果: ', ' '.join('%5s'\\\n",
    "            % classes[predicted[j]] for j in range(4)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "已经可以看出效果，准确率很高，针对这四个图片达到了75%的效果，但这只是一部分的图片，再来看看在整个测试集上的效果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10000张测试集中的准确率为: 52.000000 %\n"
     ]
    }
   ],
   "source": [
    "correct = 0 # 预测正确的图片数\n",
    "total = 0 # 总共的图片数\n",
    "\n",
    "\n",
    "# 由于测试的时候不需要求导，可以暂时关闭autograd，提高速度，节约内存\n",
    "with t.no_grad():\n",
    "    for data in testloader:\n",
    "        images, labels = data\n",
    "        outputs = net(images)\n",
    "        _, predicted = t.max(outputs, 1)\n",
    "        total += labels.size(0)\n",
    "        correct += (predicted == labels).sum()\n",
    "\n",
    "print('10000张测试集中的准确率为: %f %%' % (100 * correct //total))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "训练的准确率远比随机猜测(准确率10%)好，证明网络确实学到了东西。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**在GPU上训练**\n",
    "\n",
    "就像之前把Tensor从CPU转到GPU一样，模型也可以类似地从CPU转到GPU，以加速训练。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor(0.5668, device='cuda:0', grad_fn=<NllLossBackward>)"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "device = t.device(\"cuda:0\" if t.cuda.is_available() else \"cpu\")\n",
    "\n",
    "net.to(device)\n",
    "images = images.to(device)\n",
    "labels = labels.to(device)\n",
    "output = net(images)\n",
    "loss= criterion(output,labels)\n",
    "\n",
    "loss"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果发现在GPU上并没有比CPU提速很多，实际上是因为网络比较小，GPU没有完全发挥自己的真正实力。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 本章小结\n",
    "\n",
    "本章主要介绍了PyTorch框架的安装及其学习工具的部署，同时给出一个PyTorch的快速入门指南，具体包含以下内容：\n",
    "\n",
    "1. Tensor: 类似Numpy数组的数据结构，与Numpy接口类似，可方便地互相转换；\n",
    "2. autograd: 为Tensor提供自动求导功能。\n",
    "3. nn: 专门为神经网络设计的接口，提供了很多有用的功能(神经网络层，损失函数，优化器等)。\n",
    "4. 神经网络训练: 以CIFAR-10分类为例演示了神经网络的训练流程，包括数据加载、网络搭建、训练及测试。\n",
    "\n",
    "本章的所有内容旨在帮助读者建立一个对PyTorch框架的初步认识，并快速地使用PyTorch进行了一个简单神经网络的训练。从下一章开始，本书将深入系统地讲解PyTorch的各部分知识。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}